#ifndef CREDITUTILITY_H
#define CREDITUTILITY_H

#include <QString>
#include <QList>
#include <QMap>
#include <QJsonObject>
#include <QJsonArray>

//Mode selection key, change to your need
const QString modeSelKey="ModeSelectionKeyHere";
enum MODE {
    ResultOverview=1,
    EditActivity=2,
    QueryResult=4,
    FullAccess=7
};

//Key for Encryption, change to your need
const QString keyStr="EncryptionKeyHere";
const QString keyStuStr="EncryptionKeyForStudentsHere";
QByteArray encrypt(const QByteArray& dec_data, bool studentKey=false);
QByteArray decrypt(const QByteArray& enc_data, bool studentKey=false);
QString sha256encode(const QString& data);

enum ActivityType {
    //basic types
    noneType=0b00000,
    studentWork=0b00001,
    personalDevelopment=0b00010,
    practiceVisit=0b00100,
    voluntaryActivity=0b01000,
    communityLife=0b10000,
    //masking
    nStuWorkMask=0b11110,
    nPerDevMask=0b11101,
    nPracVisMask=0b11011,
    nVolActMask=0b10111,
    nComLifeMask=0b01111,
    allType=0b11111
};

bool isValidId(QString idStr);
bool isValidPwd(QString pwdStr);

class Student {
public:
    QString id,name,pwd;
    Student(QString _id={},QString _name={},QString _pwd={});
    ~Student() = default;

    QJsonObject getObj(bool requirePassword = true, bool sha256 = false);
    bool parseObj(const QJsonObject& stuObj);

    static QJsonArray getArr(const QList<Student>& stuList, bool requirePassword = true, bool sha256 = false);
    static QList<Student> getList(const QJsonArray& stuArray);
};

const int fullCredit = 60, categoryCredit = 10, hashSize = 161050;
typedef QPair<unsigned, ActivityType> CreditRecord; //(credit, type)
class Activity {
public:
    QString name;
    ActivityType type;
    Activity(QString _name={},ActivityType _type=noneType);
    ~Activity() = default;

    typedef QMap<QString, CreditRecord> ActivityRecord;
    QMap<QString, ActivityRecord> records;

    void merge(const Activity& that);

    QJsonObject getObj();
    bool parseObj(const QJsonObject& actObj);

    static QJsonArray getArr(const QList<Activity>& actList);
    static QList<Activity> getList(const QJsonArray& actArray);
};
QList<CreditRecord> getRecordList(const Student& student, const QList<Activity>& actList);
unsigned getTotalCredits(const Student& student, const QList<Activity>& actList);

struct categoryCreditStatus {
    unsigned stuWork, perDev, pracVis, volAct, comLife;
    unsigned hash() const;
    unsigned weight() const;
    void trunc();
    ActivityType qualification() const;
};

categoryCreditStatus checkTypeStatus(const Student& student, const QList<Activity>& actList);

#endif // CREDITUTILITY_H
